Skip to content

Rad/new ready example#77

Merged
sawradip merged 18 commits into
mainfrom
rad/new_ready_example
Nov 6, 2025
Merged

Rad/new ready example#77
sawradip merged 18 commits into
mainfrom
rad/new_ready_example

Conversation

@RadeenXALNW
Copy link
Copy Markdown
Collaborator

@RadeenXALNW RadeenXALNW commented Oct 29, 2025

Fixed RUST sdk with runagent cloud support.
Adding different saas type examples to directly deploy with RunAgent cloud.

Summary by CodeRabbit

  • New Features

    • Added Stock Trading Agent example demonstrating AI-driven stock market simulation with real-time decision-making capabilities
    • Added Book Writer Flow example showcasing multi-agent orchestration for automated book generation
    • Added Lead Scoring Agent example for AI-powered recruitment candidate evaluation
    • Added Recipe Creator Agent example with streaming recipe generation
    • Introduced modular CLI command structure with enhanced setup, configuration, and deployment workflows
    • Enhanced streaming response support across multiple client implementations
  • Documentation

    • Added comprehensive deployment guides and README files for all new example projects
    • Added CrewAI automation tutorials and best practices documentation
  • Chores

    • Reorganized CLI commands into focused modules for improved maintainability
    • Updated authentication and configuration management workflows
    • Enhanced error handling and user feedback throughout CLI

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Oct 29, 2025

Caution

Review failed

Failed to post review comments

Walkthrough

This PR adds four comprehensive AI agent example projects (StockAgent for stock trading simulation, BookWriter for AI-driven book generation, LeadAgent for hiring lead scoring, and RecipeCreator for recipe generation), restructures the RunAgent CLI from a monolithic commands module to modular command files with enhanced UX features, updates Rust client REST/WebSocket protocol implementations, and refines SDK authentication and configuration handling.

Changes

Cohort / File(s) Summary
StockAgent Example
examples/Stockagent/
Complete multi-agent stock trading simulation framework with AI agents, stock market mechanics, loan management, trading actions, Excel-based record-keeping, custom logging, and RunAgent integration; includes SDK test clients in Python and Rust.
BookWriter Example
examples/book_writer/
End-to-end AI book generation system with Flask backend API, React/TypeScript frontend, CrewAI-based book outline and chapter writing workflows, and SDK test client demonstrating outline generation and full book composition.
LeadAgent Example
examples/lead-agent/
AI-powered recruitment lead scoring platform with Flask backend, React frontend, CSV-based candidate ingestion, asynchronous scoring workflows, email generation, and comprehensive deployment guide covering local and cloud deployment patterns.
RecipeCreator Example
examples/recipe_creator/
AI recipe generation service using Agno framework with Flask backend, vanilla JS frontend with real-time streaming, ExaTools integration, and Python SDK test demonstrating both streaming and non-streaming recipe creation.
RunAgent CLI Restructuring
runagent/cli/main.py,
runagent/cli/commands/*.py
Migrated CLI from monolithic commands.py to modular command files (setup.py, config.py, delete.py, deploy.py, init.py, run.py, run_stream.py, serve.py, start.py, teardown.py, upload.py, db.py) with interactive prompts, branding utilities, and enhanced error handling. Removed legacy commands.py.
RunAgent Branding & CLI Utilities
runagent/cli/branding.py
New module providing styled ASCII logo rendering, welcome banners, and header display functions using Rich library for CLI visual enhancement.
Rust Client Protocol Updates
runagent-rust/runagent/src/client/rest_client.rs,
runagent-rust/runagent/src/client/socket_client.rs
Updated REST client to inject API key as query parameter and Authorization header; changed WebSocket endpoint from agents/{id}/execute/{entrypoint} to agents/{id}/run-stream; restructured payload serialization from SafeMessage to flat JSON; updated message parsing to handle new JSON-based protocol with status/data/error types.
Rust Client Architecture & Config
runagent-rust/runagent/src/client/runagent_client.rs,
runagent-rust/runagent/src/utils/config.rs,
runagent-rust/runagent/src/constants.rs
Made architecture loading non-fatal with fallback; added new entrypoints (simulate_stream, run) to default architecture; added user-related config fields (user_email, user_id, user_tier, auth_validated); made JSON deserialization fault-tolerant; updated default base URL to 20.84.81.110:8333.
Rust Type Schema
runagent-rust/runagent/src/types/schema.rs
Added entrypoint_tag field to WebSocketAgentRequest and ExecutionError variant to MessageType enum.
.gitignore & Version
.gitignore,
runagent/__version__.py
Fixed test.md gitignore entry; resolved version conflict to 0.1.23.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI
    participant RunAgent SDK
    participant API/Server
    participant LocalDB

    User->>CLI: runagent setup
    CLI->>CLI: show_help_with_logo()
    CLI->>CLI: show_interactive_config_menu()
    User->>CLI: Enter API Key
    CLI->>RunAgent SDK: validate_credentials()
    RunAgent SDK->>API/Server: verify_api_key
    API/Server-->>RunAgent SDK: user_info
    RunAgent SDK->>LocalDB: save_config
    CLI-->>User: Setup Complete

    User->>CLI: runagent run --agent-id <id> --tag simulate
    CLI->>RunAgent SDK: RunAgentClient(agent_id, tag)
    RunAgent SDK->>API/Server: POST /agents/{id}/run
    API/Server-->>RunAgent SDK: result
    CLI-->>User: Execution Result

    User->>CLI: runagent run --agent-id <id> --tag simulate_stream
    CLI->>RunAgent SDK: RunAgentClient.run_stream()
    RunAgent SDK->>API/Server: WebSocket /agents/{id}/run-stream
    loop Stream Messages
        API/Server-->>RunAgent SDK: {type: data, content: chunk}
        RunAgent SDK-->>CLI: chunk
        CLI-->>User: Display chunk
    end
    API/Server-->>RunAgent SDK: {type: status, status: stream_completed}
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~55 minutes

Areas requiring extra attention:

  • Rust client protocol changes (rest_client.rs, socket_client.rs): Significant refactoring of authentication (dual token/header approach) and payload serialization (SafeMessage → flat JSON); verify backward compatibility and correctness of new message parsing logic.
  • CLI restructuring (runagent/cli/main.py, runagent/cli/commands/*.py): Modular command pattern is sound, but verify error handling consistency across all command modules, especially around AuthenticationError and DISABLE_TRY_CATCH usage; ensure all interactive prompts work as expected.
  • StockAgent simulation flow (examples/Stockagent/main.py, examples/Stockagent/runagent_wrapper.py): Complex orchestration with loan decisions, trading sessions, and streaming updates; verify state management, edge cases in bankruptcy logic, and correctness of real-time streaming integration.
  • Configuration fallback behavior (utils/config.rs, runagent_client.rs): New lenient deserialization and architecture loading fallbacks could mask configuration issues; ensure appropriate logging and user visibility for degraded states.

Possibly related PRs

  • Sawra/runagent cloud support wip #73: Modifies WebSocket/REST streaming protocol, run endpoint payload structures, and entrypoint tag handling—directly overlaps with this PR's client protocol changes.
  • Sawra/runagent cloud support wip #71: Restructures CLI command modules, updates Framework enum, and modifies REST client auth/payload serialization—similar scope to this PR's CLI and Rust client work.
  • Sawra/runagent cloud support #69: Overlapping changes to CLI commands, messaging protocol MessageType variants, and run/run-stream endpoint handling.

Suggested reviewers

  • sawradip

Poem

🐰 Hops through code both vast and wide,
Four new agents now reside,
CLI modular, shiny new,
Rust runs faster, protocols true,
RunAgent leaps to greater heights! 🚀

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.01% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title Check ❓ Inconclusive The pull request title "Rad/new ready example" is partially related to the changeset but exhibits issues with clarity and completeness. The PR objectives indicate two main goals: "Fixed RUST SDK with RunAgent Cloud support" and "Added different SaaS-type examples," yet the title only addresses the examples aspect and uses vague terminology. The title appears to include a branch name prefix ("Rad/") which is unconventional for PR titles, and "new ready example" is somewhat generic without clearly specifying what type of examples or what makes them "ready." While the PR does introduce multiple new SaaS examples (StockAgent, BookWriter, LeadAgent, RecipeCreator), the title omits the significant Rust SDK improvements for cloud support that are explicitly mentioned in the PR objectives, resulting in an incomplete representation of the changeset's scope. Consider revising the title to be more descriptive and comprehensive. A stronger title might be something like "Add SaaS examples and improve Rust SDK cloud support" or "Add ready-to-deploy SaaS examples (StockAgent, BookWriter, LeadAgent, RecipeCreator) and enhance Rust SDK for RunAgent Cloud." This would clearly communicate both major aspects of the change and remove the branch name prefix, making the title more suitable for historical reference and teammate scanning.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch rad/new_ready_example

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 82

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
runagent-rust/runagent/src/client/socket_client.rs (2)

80-81: Do not log secrets in WebSocket URLs

url includes ?token=...; logging it leaks the API key.

Apply this diff to redact the query before logging:

-        tracing::debug!("Connecting to WebSocket: {}", url);
+        let mut safe_url = url.clone();
+        safe_url.set_query(None);
+        tracing::debug!("Connecting to WebSocket: {}", safe_url);

206-209: Fix broken unit test: expected path is outdated

Update expected URL to run-stream.

Apply this diff:

-        assert_eq!(url.as_str(), "ws://localhost:8000/api/v1/agents/test-agent/execute/generic");
+        assert_eq!(url.as_str(), "ws://localhost:8000/api/v1/agents/test-agent/run-stream");
runagent-rust/runagent/src/utils/config.rs (2)

100-105: Harden secret writes: atomic write + restrictive permissions (0o600)

Config may contain API keys. Write atomically and restrict file mode to user‑read/write.

-        let content = serde_json::to_string_pretty(self)
-            .map_err(|e| RunAgentError::config(format!("Failed to serialize config: {}", e)))?;
-
-        fs::write(&config_path, content)
-            .map_err(|e| RunAgentError::config(format!("Failed to write config file: {}", e)))?;
+        let content = serde_json::to_string_pretty(self)
+            .map_err(|e| RunAgentError::config(format!("Failed to serialize config: {}", e)))?;
+
+        // Atomic write via temp file
+        let tmp_path = config_path.with_extension("tmp");
+        fs::write(&tmp_path, &content)
+            .map_err(|e| RunAgentError::config(format!("Failed to write temp config file: {}", e)))?;
+
+        // Tighten permissions on Unix
+        #[cfg(unix)]
+        {
+            use std::os::unix::fs::PermissionsExt;
+            fs::set_permissions(&tmp_path, fs::Permissions::from_mode(0o600))
+                .map_err(|e| RunAgentError::config(format!("Failed to set config perms: {}", e)))?;
+        }
+
+        fs::rename(&tmp_path, &config_path)
+            .map_err(|e| RunAgentError::config(format!("Failed to persist config file: {}", e)))?;

346-353: Based on my verification, I can now confirm the path traversal vulnerability and provide a rewritten review comment.

Path traversal vulnerability in deployment file paths requires sanitization

Both save_deployment_info (lines 346–353) and get_deployment_info (lines 363–366) interpolate agent_id directly into file paths without validation. This allows crafted values like ../../foo or ../etc/passwd to escape .deployments/ and read/write arbitrary files.

Since these are public library functions, external callers can provide untrusted agent_id values. Sanitize to a safe character set before joining:

-        let info_file = deployments_dir.join(format!("{}.json", agent_id));
+        // Sanitize to prevent path traversal / absolute paths
+        let safe_id: String = agent_id.chars()
+            .map(|c| if c.is_ascii_alphanumeric() || c == '_' || c == '-' { c } else { '_' })
+            .collect();
+        let info_file = deployments_dir.join(format!("{}.json", safe_id));

Note: The same vulnerability exists in the Python equivalent (runagent/utils/config.py lines 213, 230).

Comment on lines +178 to +180
if __name__ == '__main__':
port = int(os.getenv('PORT', 8000))
app.run(host='0.0.0.0', port=port, debug=True) No newline at end of file
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Disable Flask debug and don’t bind to all interfaces by default.

Debug mode exposes an interactive console and sensitive data; binding 0.0.0.0 in dev is fine but should be explicit.

-if __name__ == '__main__':
-    port = int(os.getenv('PORT', 8000))
-    app.run(host='0.0.0.0', port=port, debug=True)
+if __name__ == '__main__':
+    port = int(os.getenv('PORT', 8000))
+    debug = os.getenv('FLASK_DEBUG', '0') == '1'
+    host = os.getenv('FLASK_BIND', '127.0.0.1')
+    app.run(host=host, port=port, debug=debug)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if __name__ == '__main__':
port = int(os.getenv('PORT', 8000))
app.run(host='0.0.0.0', port=port, debug=True)
if __name__ == '__main__':
port = int(os.getenv('PORT', 8000))
debug = os.getenv('FLASK_DEBUG', '0') == '1'
host = os.getenv('FLASK_BIND', '127.0.0.1')
app.run(host=host, port=port, debug=debug)
🧰 Tools
🪛 ast-grep (0.39.6)

[warning] 179-179: Detected Flask app with debug=True. Do not deploy to production with this flag enabled as it will leak sensitive information. Instead, consider using Flask configuration variables or setting 'debug' using system environment variables.
Context: app.run(host='0.0.0.0', port=port, debug=True)
Note: [CWE-489] Active Debug Code. [REFERENCES]
- https://labs.detectify.com/2015/10/02/how-patreon-got-hacked-publicly-exposed-werkzeug-debugger/

(debug-enabled-python)

🪛 Ruff (0.14.2)

180-180: Possible binding to all interfaces

(S104)


180-180: Use of debug=True in Flask app detected

(S201)

🤖 Prompt for AI Agents
In examples/book_writer/backend/app.py around lines 178 to 180, the code starts
the Flask app with debug=True and host='0.0.0.0'; change this so debug is
disabled by default and the server binds to localhost by default. Read HOST and
DEBUG (or FLASK_DEBUG) from environment variables (e.g. host = os.getenv('HOST',
'127.0.0.1'); debug = os.getenv('DEBUG', os.getenv('FLASK_DEBUG',
'false')).lower() == 'true') and pass those into app.run so developers must
explicitly set the env var to enable remote binding or debug mode.

Comment on lines +784 to +870
#### 1. Installation

**Step 1: Install Python**

Ensure that you have Python installed on your system. You can download the latest version of Python from the [official website](https://www.python.org/downloads/).

**Step 2: Install CrewAI**

To install CrewAI, open your terminal (Command Prompt for Windows, Terminal for macOS and Linux) and run the following command:

```sh
pip install crewai
```

For additional tools, you can use:

```sh
pip install 'crewai[tools]'
```

#### 2. Configuration

**Step 3: Setting Up Configuration Files**

CrewAI requires some configuration to function correctly. Create a configuration file named `crewai_config.yaml` in your project directory. Here is a basic template:

```yaml
api_key: YOUR_API_KEY
project_id: YOUR_PROJECT_ID
```

Replace `YOUR_API_KEY` and `YOUR_PROJECT_ID` with your actual API key and project ID from CrewAI.

**Step 4: Setting Environment Variables**

You can also set environment variables for sensitive information, such as API keys. For example, on Unix-based systems, you can add to your `.bashrc` or `.zshrc`:

```sh
export CREWAI_API_KEY="YOUR_API_KEY"
export CREWAI_PROJECT_ID="YOUR_PROJECT_ID"
```

#### 3. Creating the First AI Agent

**Step 5: Import CrewAI and Set Up the Agent**

Open your Python IDE or text editor and create a new Python file (e.g., `create_agent.py`). Add the following code:

```python
import crewai

# Initialize CrewAI client
client = crewai.Client(api_key="YOUR_API_KEY", project_id="YOUR_PROJECT_ID")

# Define the AI agent
agent = {
"name": "EmailResponder",
"description": "Automates email responses based on predefined templates.",
"tasks": [
{
"name": "Check new emails",
"action": "check_email",
"frequency": "every 5 minutes"
},
{
"name": "Respond to emails",
"action": "respond_email",
"template": "Thank you for your email. We will get back to you shortly."
}
]
}

# Create the agent
response = client.create_agent(agent)

print(f"Agent created: {response}")
```

**Step 6: Running the Agent**

Run your Python script to create and start the AI agent:

```sh
python create_agent.py
```

You should see an output indicating that the agent has been successfully created.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use Markdown headings for step headers instead of bold emphasis.

Lines 786, 790, 806, 817, 828, and 862 use bold text (**Step N: ...**) for step headers, which violates Markdown best practices. These should be promoted to h3 headings (###) to improve document structure and accessibility.

Apply this diff to convert step headers to proper headings:

-**Step 1: Install Python**
+### Step 1: Install Python

-**Step 2: Install Git**
+### Step 2: Install Git

-**Step 3: Set Up Virtual Environment**
+### Step 3: Set Up Virtual Environment

-**Step 4: Clone CrewAI Repository**
+### Step 4: Clone CrewAI Repository

-**Step 5: Install Dependencies**
+### Step 5: Install Dependencies

-**Step 6: Run CrewAI**
+### Step 6: Run CrewAI

Repeat this pattern for the macOS and Linux installation sections.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#### 1. Installation
**Step 1: Install Python**
Ensure that you have Python installed on your system. You can download the latest version of Python from the [official website](https://www.python.org/downloads/).
**Step 2: Install CrewAI**
To install CrewAI, open your terminal (Command Prompt for Windows, Terminal for macOS and Linux) and run the following command:
```sh
pip install crewai
```
For additional tools, you can use:
```sh
pip install 'crewai[tools]'
```
#### 2. Configuration
**Step 3: Setting Up Configuration Files**
CrewAI requires some configuration to function correctly. Create a configuration file named `crewai_config.yaml` in your project directory. Here is a basic template:
```yaml
api_key: YOUR_API_KEY
project_id: YOUR_PROJECT_ID
```
Replace `YOUR_API_KEY` and `YOUR_PROJECT_ID` with your actual API key and project ID from CrewAI.
**Step 4: Setting Environment Variables**
You can also set environment variables for sensitive information, such as API keys. For example, on Unix-based systems, you can add to your `.bashrc` or `.zshrc`:
```sh
export CREWAI_API_KEY="YOUR_API_KEY"
export CREWAI_PROJECT_ID="YOUR_PROJECT_ID"
```
#### 3. Creating the First AI Agent
**Step 5: Import CrewAI and Set Up the Agent**
Open your Python IDE or text editor and create a new Python file (e.g., `create_agent.py`). Add the following code:
```python
import crewai
# Initialize CrewAI client
client = crewai.Client(api_key="YOUR_API_KEY", project_id="YOUR_PROJECT_ID")
# Define the AI agent
agent = {
"name": "EmailResponder",
"description": "Automates email responses based on predefined templates.",
"tasks": [
{
"name": "Check new emails",
"action": "check_email",
"frequency": "every 5 minutes"
},
{
"name": "Respond to emails",
"action": "respond_email",
"template": "Thank you for your email. We will get back to you shortly."
}
]
}
# Create the agent
response = client.create_agent(agent)
print(f"Agent created: {response}")
```
**Step 6: Running the Agent**
Run your Python script to create and start the AI agent:
```sh
python create_agent.py
```
You should see an output indicating that the agent has been successfully created.
#### 1. Installation
### Step 1: Install Python
Ensure that you have Python installed on your system. You can download the latest version of Python from the [official website](https://www.python.org/downloads/).
### Step 2: Install CrewAI
To install CrewAI, open your terminal (Command Prompt for Windows, Terminal for macOS and Linux) and run the following command:
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

786-786: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


790-790: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


806-806: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


817-817: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


828-828: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


862-862: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

🤖 Prompt for AI Agents
In examples/book_writer/write_a_book_with_flows/Automating_Tasks_with_CrewAI.md
around lines 784–870, several step headers are formatted using bold text (lines
~786, 790, 806, 817, 828, 862); replace each bold "Step N: ..." line with a
Markdown H3 heading (### Step N: ...) to follow proper heading semantics and
accessibility, and apply the same replacement for the macOS and Linux
installation subsections elsewhere in the installation section so all step
headers use consistent H3 headings.

Comment on lines +1043 to +1048
# Automating Complex Workflows with CrewAI

### Advanced Task Automation Techniques

In this chapter, we'll explore advanced techniques for automating complex workflows using CrewAI. We'll delve into real-world examples, such as automating data analysis and report generation, and provide best practices for managing intricate automation tasks. By the end of this chapter, you'll be equipped to tackle more sophisticated automation challenges with confidence.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix heading level hierarchy at line 1045.

The heading ### Advanced Task Automation Techniques (line 1045) should be ## (h2) to properly follow the document hierarchy. After the chapter section introduction, the first major subsection should be h2, not h3.

-### Advanced Task Automation Techniques
+## Advanced Task Automation Techniques
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Automating Complex Workflows with CrewAI
### Advanced Task Automation Techniques
In this chapter, we'll explore advanced techniques for automating complex workflows using CrewAI. We'll delve into real-world examples, such as automating data analysis and report generation, and provide best practices for managing intricate automation tasks. By the end of this chapter, you'll be equipped to tackle more sophisticated automation challenges with confidence.
# Automating Complex Workflows with CrewAI
## Advanced Task Automation Techniques
In this chapter, we'll explore advanced techniques for automating complex workflows using CrewAI. We'll delve into real-world examples, such as automating data analysis and report generation, and provide best practices for managing intricate automation tasks. By the end of this chapter, you'll be equipped to tackle more sophisticated automation challenges with confidence.
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

1045-1045: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)

🤖 Prompt for AI Agents
In examples/book_writer/write_a_book_with_flows/Automating_Tasks_with_CrewAI.md
around lines 1043–1048, the subsection heading at line 1045 is using "###
Advanced Task Automation Techniques" but should be an h2 to follow the chapter
introduction; change the heading marker from "###" to "##" so the section
becomes "## Advanced Task Automation Techniques" to fix the document hierarchy.

Comment on lines +1908 to +1932
### Official CrewAI Documentation

The official documentation is a comprehensive resource that covers everything from basic setup to advanced features. It is an essential guide for mastering CrewAI.

- [CrewAI Documentation](https://docs.crewai.com)

### CrewAI Community Forum

The community forum is a great place to ask questions, share ideas, and connect with other CrewAI users. It's a supportive environment where you can find solutions and collaborate on projects.

- [CrewAI Community Forum](https://forum.crewai.com)

### Tutorials and Guides

Online tutorials and guides offer step-by-step instructions and practical examples to help you get the most out of CrewAI. These resources are perfect for both beginners and advanced users.

- [CrewAI Tutorials on YouTube](https://youtube.com/crewai)

### Books and Articles

There are numerous books and articles available on AI and task automation. These resources provide deeper insights and broader perspectives on the subject, enhancing your knowledge and expertise.

### Webinars and Workshops

Participating in webinars and workshops can provide hands-on experience and direct interaction with experts. Keep an eye out for events hosted by CrewAI and other industry leaders.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify CrewAI documentation and community links are current and accessible.

Lines 1912, 1917, and 1924 reference CrewAI documentation, forum, and tutorial URLs. Please verify these links are valid, current, and correctly reflect the actual locations of these resources. Broken links in user-facing documentation can degrade the reader experience and reduce the handbook's usefulness.


🌐 Web query:

What is the official CrewAI documentation URL, community forum URL, and where are their video tutorials located?

💡 Result:

  • Official documentation: https://docs.crewai.com/en/index. [1]
  • Community forum: https://community.crewai.com. [2]
  • Video tutorials: CrewAI’s YouTube tutorials/playlist are linked from the community and docs (examples of videos posted on the community and a curated YouTube playlist on the open‑source page). [3][4]

Sources: [1] CrewAI Docs; [2] CrewAI Community; [3] CrewAI community YouTube post; [4] CrewAI open‑source page (curated playlist).


Update CrewAI community forum URL and verify YouTube tutorial link.

Line 1917 contains an incorrect community forum URL. The correct URL is https://community.crewai.com, not forum.crewai.com.

Additionally, line 1924 references https://youtube.com/crewai for tutorials, but this could not be verified. CrewAI's YouTube tutorials are linked from the community and docs pages with a curated playlist. Consider verifying or updating this link to point directly to the verified tutorial location.

🤖 Prompt for AI Agents
In examples/book_writer/write_a_book_with_flows/Automating_Tasks_with_CrewAI.md
around lines 1908 to 1932, the community forum URL is incorrect and the YouTube
link is unverified; update the forum link from https://forum.crewai.com to
https://community.crewai.com, and verify the correct CrewAI YouTube tutorials
URL — if a direct playlist URL exists use that exact verified link, otherwise
replace the YouTube link with a pointer to the tutorials page on the official
docs or community pages (e.g., "See tutorials linked on the CrewAI
Docs/Community") so the reference is accurate.

Comment on lines +1 to +4
crewai==1.2.1
langchain-tools
pydantic
nest-asyncio No newline at end of file
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Specify versions for all dependencies for reproducibility.

Only crewai is pinned to a specific version while langchain-tools, pydantic, and nest-asyncio lack version constraints. This inconsistency can lead to reproducibility issues and unexpected breaking changes across different environments. Given this is a deployment example for RunAgent Cloud, explicit version management is critical.

Apply this diff to pin all dependencies:

 crewai==1.2.1
-langchain-tools
-pydantic
-nest-asyncio
+langchain-tools>=0.0.1
+pydantic>=2.0
+nest-asyncio>=1.5.0

Adjust the version constraints based on the actual versions tested and compatible with crewai==1.2.1.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
crewai==1.2.1
langchain-tools
pydantic
nest-asyncio
crewai==1.2.1
langchain-tools>=0.0.1
pydantic>=2.0
nest-asyncio>=1.5.0
🤖 Prompt for AI Agents
In examples/book_writer/write_a_book_with_flows/requirements.txt lines 1-4, only
crewai is version-pinned while langchain-tools, pydantic, and nest-asyncio are
unpinned; update the file to specify exact or constrained versions for those
three packages (choose the tested compatible versions with crewai==1.2.1, e.g.,
langchain-tools==<tested>, pydantic==<tested>, nest-asyncio==<tested>) to ensure
reproducible installs and avoid breakages.

Comment on lines +18 to 23
pub user_email: Option<String>,
pub user_id: Option<String>,
pub user_tier: Option<String>,
pub auth_validated: Option<bool>,
#[serde(default)]
pub user_info: HashMap<String, serde_json::Value>,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

New user_ fields never loaded from file*

You added user_email/user_id/user_tier/auth_validated but load() doesn’t merge them from file_config. They’ll always be None, breaking any features depending on them.

Apply this merge in load():

         if let Ok(file_config) = Self::load_from_file() {
             config.api_key = file_config.api_key.or(config.api_key);
             config.base_url = if file_config.base_url.is_empty() {
                 config.base_url
             } else {
                 file_config.base_url
             };
+            config.user_email = file_config.user_email.or(config.user_email);
+            config.user_id = file_config.user_id.or(config.user_id);
+            config.user_tier = file_config.user_tier.or(config.user_tier);
+            config.auth_validated = file_config.auth_validated.or(config.auth_validated);
             config.user_info.extend(file_config.user_info);
         }

Also applies to: 46-54

🤖 Prompt for AI Agents
In runagent-rust/runagent/src/utils/config.rs around lines 18 to 23 (and
similarly for the block at lines 46–54), the new fields user_email, user_id,
user_tier, and auth_validated are declared but not merged from file_config in
load(), so they remain None; update the load() logic to copy/merge these four
fields from file_config into the in-memory Config instance when present
(respecting Option semantics so existing in-memory values aren't overwritten
unless file_config has Some), and ensure user_info continues to be merged with
serde/default handling.

Comment on lines +81 to +84
match serde_json::from_str::<Self>(&content) {
Ok(parsed_config) => Ok(parsed_config),
Err(_) => Ok(Self::default())
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don’t silently drop corrupted config; back up and surface the error

Defaulting on JSON parse failure hides corruption and can erase user settings. At minimum, back up the original and return a clear error (or emit a warning if you must keep a tolerant path).

Suggested safer handling:

-            match serde_json::from_str::<Self>(&content) {
-                Ok(parsed_config) => Ok(parsed_config),
-                Err(_) => Ok(Self::default())
-            }
+            match serde_json::from_str::<Self>(&content) {
+                Ok(parsed_config) => Ok(parsed_config),
+                Err(e) => {
+                    let backup_path = config_path.with_extension(
+                        format!("corrupted-{}.json", chrono::Utc::now().timestamp())
+                    );
+                    let _ = fs::write(&backup_path, &content);
+                    Err(RunAgentError::config(
+                        format!(
+                            "Invalid config JSON: {}. Original backed up to {}",
+                            e, backup_path.display()
+                        )
+                    ))
+                }
+            }

If you strongly prefer tolerance, at least log a warning and still create the backup before returning Default.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In runagent-rust/runagent/src/utils/config.rs around lines 81 to 84, the code
currently swallows JSON parse errors and returns Default; instead, detect the
serde_json::from_str error, create a timestamped backup of the original config
file content (write to config_path.with_extension(".corrupt.<timestamp>.json")
or similar), then propagate a clear error (return Err with the serde_json error
wrapped in your crate error type) so the caller can handle it; if you must
remain tolerant, at minimum log a warning with the parse error and the backup
path before returning Ok(Self::default()).

Comment on lines +95 to +103
raise click.UsageError(
"Cannot specify both --agent-id and --host/--port. "
"Choose one approach."
)

if not agent_id_provided and not host_port_provided:
raise click.UsageError(
"Must specify either --agent-id or both --host and --port."
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Align option names in errors and examples

The option is --id, not --agent-id.

-            "Cannot specify both --agent-id and --host/--port. "
+            "Cannot specify both --id and --host/--port. "
@@
-            "Must specify either --agent-id or both --host and --port."
+            "Must specify either --id or both --host and --port."

And in the examples:

-        runagent run --agent-id my-agent --param1=value1 --param2=value2
+        runagent run --id my-agent --param1=value1 --param2=value2

Also applies to: 73-84

🧰 Tools
🪛 Ruff (0.14.2)

95-98: Avoid specifying long messages outside the exception class

(TRY003)


101-103: Avoid specifying long messages outside the exception class

(TRY003)

🤖 Prompt for AI Agents
In runagent/cli/commands/run.py around lines 73-84 and 95-103, the usage error
messages reference the wrong option name `--agent-id`; change the text to use
the correct option `--id` and update any example strings shown in those messages
to match the actual CLI flag (`--id` vs `--agent-id`). Ensure both the
mutually-exclusive error and the "must specify" error use `--id` consistently
and adjust any example usage in the surrounding lines so they reflect `--id` and
the correct `--host`/`--port` combinations.

Comment on lines +24 to +26
from runagent.utils.config import Config
from runagent.sdk.deployment.middleware_sync import get_middleware_sync
from runagent.cli.utils import add_framework_options, get_selected_framework
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix API key lookup: wrong symbol

get_api_key() is a module-level function; Config.get_api_key() will raise AttributeError.

-from runagent.utils.config import Config
+from runagent.utils.config import Config, get_api_key
@@
-            sync_service = get_middleware_sync()
-            sync_enabled = sync_service.is_sync_enabled()
-            api_key_set = bool(Config.get_api_key())
+            sync_service = get_middleware_sync()
+            sync_enabled = sync_service.is_sync_enabled() if sync_service else False
+            api_key_set = bool(get_api_key())

Also applies to: 178-181

🤖 Prompt for AI Agents
In runagent/cli/commands/serve.py around lines 24-26 (and also at lines 178-181)
the code calls Config.get_api_key(), but get_api_key is a module-level function
and Config has no such method; replace calls to Config.get_api_key() with
get_api_key(), and ensure you import it at the top (from runagent.utils.config
import get_api_key) so the function is available where invoked.

Comment on lines +69 to +75
try:
config_dict = json.loads(config)
except json.JSONDecodeError:
if os.getenv('DISABLE_TRY_CATCH'):
raise
raise click.ClickException("Invalid JSON in config parameter")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Chain JSON decode errors and improve message

Preserve the original cause and clarify the option name.

Apply:

-            except json.JSONDecodeError:
+            except json.JSONDecodeError as err:
                 if os.getenv('DISABLE_TRY_CATCH'):
                     raise
-                raise click.ClickException("Invalid JSON in config parameter")
+                raise click.ClickException("Invalid JSON in --config value") from err
🧰 Tools
🪛 Ruff (0.14.2)

74-74: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)


74-74: Avoid specifying long messages outside the exception class

(TRY003)

🤖 Prompt for AI Agents
In runagent/cli/commands/start.py around lines 69 to 75, the JSON decode except
block should preserve the original exception as the cause and clarify the
environment variable name in the message: catch the json.JSONDecodeError as e,
if os.getenv('DISABLE_TRY_CATCH') is set re-raise e, otherwise raise
click.ClickException("Invalid JSON in --config parameter; set
DISABLE_TRY_CATCH=1 to see the raw error") from e so the original error is
chained for debugging.

@sawradip sawradip merged commit 876cb05 into main Nov 6, 2025
2 checks passed
This was referenced Nov 6, 2025
@coderabbitai coderabbitai Bot mentioned this pull request Dec 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants